
package com.thinkgem.jeesite.modules.cms.web.front;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.constant.Constant;
import com.thinkgem.jeesite.common.json.Tip;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
import com.thinkgem.jeesite.common.servlet.ValidateCodeServlet;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.IdGen;
import com.thinkgem.jeesite.common.utils.ParamMap;
import com.thinkgem.jeesite.common.utils.ZxingUtils;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.cms.entity.Site;
import com.thinkgem.jeesite.modules.cms.utils.CmsUtils;
import com.thinkgem.jeesite.modules.ems.entity.Award;
import com.thinkgem.jeesite.modules.ems.entity.Course;
import com.thinkgem.jeesite.modules.ems.entity.Join;
import com.thinkgem.jeesite.modules.ems.entity.Order;
import com.thinkgem.jeesite.modules.ems.service.AwardService;
import com.thinkgem.jeesite.modules.ems.service.CourseService;
import com.thinkgem.jeesite.modules.ems.service.JoinService;
import com.thinkgem.jeesite.modules.ems.service.OrderService;
import com.thinkgem.jeesite.modules.sys.entity.Mdict;
import com.thinkgem.jeesite.modules.sys.service.MdictService;

/**
 * 报名管理Controller
 * @author zad
 * @version 2017-10-16
 */
@Controller
@RequestMapping(value = "${frontPath}/ems")
public class FrontEmsController extends BaseController{
	
	private static org.apache.log4j.Logger logger = LogManager.getLogger("FrontEmsController");
	
	@Autowired
	private CourseService courseService;
	
	@Autowired
	private JoinService joinService;
	
	@Autowired
	private MdictService mdictService;
	
	@Autowired
	private OrderService orderService;
	
	@Autowired
	private AwardService awardService;

	/**
	 * 报名简章页面
	 */
	@RequestMapping(value = "rule")
	public String rule(String sign,Model model) {
		Site site = CmsUtils.getSite(Site.defaultSiteId());
		model.addAttribute("site", site);
		model.addAttribute("isIndex", true);
		
		// 根据课程标识，查询课程信息
		Course course = this.courseService.get(sign);
		model.addAttribute("course", course);
		
		// add by zad 2018-03-13 是否开启pc端支付
		String isPcPay = Global.isPcPay();
		model.addAttribute("isPcPay", isPcPay);
		
		return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinRule";
	}
	
	/**
	 * 报名信息填写页面
	 */
	@RequestMapping(value = "joinForm")
	public String joinForm(String sign,Model model,HttpServletRequest req,HttpServletResponse rsp) {
		Site site = CmsUtils.getSite(Site.defaultSiteId());
		model.addAttribute("site", site);
		model.addAttribute("isIndex", true);
		
		Course course = this.courseService.get(sign);
		if(null ==course)
		{
			return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
		}
		
		// 展示大类
		List<Mdict> bigCategories = null;
		Mdict mdict = new Mdict();
		mdict.setType(Constant.Mdict.MDICT_COURSE_TYPE_PREFIX + sign);
		bigCategories = this.mdictService.findList(mdict);
		
		model.addAttribute("course", course);
		model.addAttribute("bigCategories", bigCategories);
		
		// 生成token避免重复提交
		String token = IdGen.uuid();
		model.addAttribute("token", token);
		/*Map<String,Object>map = model.asMap();
		String message = null == map.get("message")?"" : String.valueOf(map.get("message"));
		model.addAttribute("message",message);*/
		req.getSession().setAttribute("token", token);
		return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinForm";
	}
	
	
	/**
	 * 报名信息查询页面
	 */
	@RequestMapping(value = "joinSearch")
	public String joinSearch(String sign,Model model,HttpServletRequest req,HttpServletResponse rsp) {
		Site site = CmsUtils.getSite(Site.defaultSiteId());
		model.addAttribute("site", site);
		model.addAttribute("isIndex", true);
		
		Course course = this.courseService.get(sign);
		
		if(null ==course)
		{
			return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
		}
		model.addAttribute("course", course);
		
		return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinSearch";
	}
	
	/**
	 * 报名信息查询结果页面
	 */
	@RequestMapping(value = "joinResult")
	public String joinResult(String sign,Join join,Model model,HttpServletRequest req,HttpServletResponse rsp) {
		Site site = CmsUtils.getSite(Site.defaultSiteId());
		model.addAttribute("site", site);
		model.addAttribute("isIndex", true);
		
		Course course = this.courseService.get(sign);
		join.setCourse(course);
		if(null ==course)
		{
			return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
		}
		model.addAttribute("course", course);
		
		/*List<Join> joins = this.joinService.findListForSearch(join);
		
		if(null == joins || joins.size() < 1)
		{
			model.addAttribute("noData", "yes");
			return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinResult";
		}*/
		
		Award award = new Award();
		award.setJoiner(join.getJoiner());
		List<Award> awards = this.awardService.findList(award);
		
		// 修改为通过sql查询 zhanganda 2017-12-08
		/*for(Join j:joins)
		{
			// 查询展示小类（因小类无法通过sql查询，只能后台处理）
			String ptype = Constant.Mdict.MDICT_COURSE_TYPE_PREFIX + sign;
			Mdict mdict = new Mdict();
			mdict.setPtype(ptype);
			mdict.setType(ptype + "_" + j.getBigCategory());
			List<Mdict> mdicts = this.mdictService.findList(mdict);
			j.setSmallCategoryName(mdictService.mdictName(mdicts, j.getSmallCategory()));
		}*/
		
		//model.addAttribute("joins", joins);
		
		model.addAttribute("awards", awards);
		
		if(null == awards || awards.size() < 1)
		{
			model.addAttribute("noData", "yes");
		}
		
		String isPcPay = Global.getConfig("isPcPay");
		model.addAttribute("isPcPay", isPcPay);
		
		return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinResult";
	}
	
	
	@RequestMapping("qryCategory")
	public String qrySubCategory(String type, HttpServletRequest req,HttpServletResponse rsp)
	{
		Mdict mdict = new Mdict();
		mdict.setType(type);
		List<Mdict> mdicts = mdictService.findList(mdict);
		String jsonStr = JsonMapper.toJsonString(mdicts);
		try {
			rsp.getWriter().print(jsonStr);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
     * add by zhangad 2017-10-19
     * 生成报名订单
     * @param model 页面模型
     * @return 结果
     */
    @RequestMapping(value="/createOrder")
    @ResponseBody
    // @AdminControllerLog(description = "课程报名订单" )
    public Tip createOrder(HttpServletRequest req,HttpServletResponse rsp,ModelMap model) throws Exception {
    	
    	Tip tip=new Tip(1,null);
    	
    	String validateCode = req.getParameter(ValidateCodeServlet.VALIDATE_CODE); // AJAX验证，成功返回true
		if (StringUtils.isNotBlank(validateCode)){
			String isCodeRight = ValidateCodeServlet.validate(req, validateCode)?"true":"false";
			// 不匹配，则返回错误信息
			if("false".equalsIgnoreCase(isCodeRight))
			{
				tip.setSuccess(false);
				tip.setData("验证码输入错误，请重新输入");
				return tip;
			}
		}
    	
    	
    	ParamMap paramMap = new ParamMap(req);
    	
    	//生成订单号
    	String orderNo=DateUtils.formatDate(new Date(),"yyyyMMddHHmmssSSS");
    	
    	//生成订单号
    	String orderId=IdGen.uuid();
    	Order order=new Order();
    	order.setIsNewRecord(true);
		order.setId(orderId);
		order.setOrderNo(orderNo);
		order.setName("课程报名订单");
		order.setStatus(Constant.Order.EMS_ORDER_STATUS_TOPAY);
		order.setSubmitTime(new Date());
		
		
    	try
    	{
    		String courseId = String.valueOf(paramMap.get("course.id"));
        	String register = String.valueOf(paramMap.get("register"));
        	String mobile = String.valueOf(paramMap.get("mobile"));
        	String groupType = String.valueOf(paramMap.get("groupType"));
        	String joinType = String.valueOf(paramMap.get("joinType"));
        	String joiner = String.valueOf(paramMap.get("joiner"));
        	String orderFrom = String.valueOf(paramMap.get("orderFrom"));
        	//String school = String.valueOf(paramMap.get("school"));
        	String remarks = String.valueOf(paramMap.get("remarks"));
        	
        	
        	Course course = this.courseService.get(courseId);
        	
        	order.setCourseId(courseId);
        	order.setGroupType(groupType);
        	order.setRegister(register);
        	order.setMobile(mobile);
        	order.setJoiner(joiner);
        	order.setOrderFrom(orderFrom);
        	order.setRemarks(remarks);
        	
        	/*Map<String,Object> map = */this.courseService.sumNumAndMoney(joinType, course.getOneMoney(), course.getMultiMoney(), joiner,order);
    		/*Object rs = map.get("success");
    		if("false".equals(String.valueOf(rs)))
    		{
    			String msg = String.valueOf(map.get("msg"));
    			tip.setSuccess(false);
        		tip.setData("生成订单失败," + msg);
        		return tip;
    		}*/
    		
	    	//生成订单
	    	orderService.save(order);
	    	tip.setSuccess(true);
    		// 成功后记录，订单id，用于充值失败后，订单状态修改
    		tip.setData(orderId);
    	}catch(Exception e)
    	{
    		e.printStackTrace();
    		tip.setSuccess(false);
    		tip.setData("生成订单失败," + e.getMessage());
    	}
    	
    	return tip;
    }
    
    @RequestMapping(value = "saveJoin")
	public String save(Join join, Model model, String token,HttpServletRequest req,RedirectAttributes redirectAttributes) throws Exception {
    	Site site = CmsUtils.getSite(Site.defaultSiteId());
    	
    	String tokenSession = null == req.getSession().getAttribute("token")?null:String.valueOf(req.getSession().getAttribute("token"));
    	
    	Order order = null;
    	List<Join> joins = this.joinService.findList(join);
    	// 若报名已成功并且订单状态为未支付，则直接到二维码支付页面(应对用户对支付页面进行刷新操作)
    	if(null != joins && joins.size() > 0)
    	{
    		order = joins.get(0).getOrder();
    		// 报名已成功并且订单状态为未支付，则直接到二维码支付页面
    		if(Constant.Order.EMS_ORDER_STATUS_TOPAY.equals(order.getStatus()))
    		{
    			return this.toQRcodePay(join, model, req);
    		}
    		else
    		{
    			return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
    		}
    	}
    	
    	order = this.orderService.get(join.getOrder().getId());
    	// 防止重复提交
    	if(null != token && token.equals(tokenSession)){
    		
			join.setOrder(order);
			try{
				join.setCourse(this.courseService.get(join.getCourse().getId()));
				this.courseService.sumNumAndMoney(join.getJoinType(), join.getCourse().getOneMoney(), join.getCourse().getMultiMoney(), join.getJoiner(),join.getOrder());
				
				model.addAttribute("join", join);
				join.setCreateDate(new Date());
				
				// 此处不再将报名人分开单独处理，2017-12-04 zad
				// 将多个选手名称及对应id转换为list，用用后台批量插入
				// joinService.parseJionList(join);
				
				// 不再将报名人分开进行批量保存, 2017-12-04 zad
				// int rows = joinService.saveBatch(join);
				joinService.save(join);
				
				/*System.out.println("前台pc端报名信息保存：家长姓名："+join.getRegister()+"家长手机号："+join.getMobile()+",报名人数：" + order.getNum()+",插入报名信息条数：" + rows + "所有选手姓名：" + join.getJoiner());
				logger.info("前台pc端报名信息保存：家长姓名："+join.getRegister()+"家长手机号："+join.getMobile()+",报名人数：" + order.getNum()+",插入报名信息条数：" + rows + "所有选手姓名：" + join.getJoiner());
				if(rows < 1)
				{
					throw new Exception("插入报名信息条数为0");
				}*/
				
				
				if(null != order)
				{
					// 生成二维码
					ZxingUtils.zxingQrcode(req, order);
					
					// String path = Global.getConfig("payQRCodePath");
					
					
					model.addAttribute("payQRCodeUrl", getVDir("payQRCodePath") + "/" + order.getOrderNo() + ".png");
				}
				
				
			}catch(Exception e)
			{
				e.printStackTrace();
				
				// addMessage(redirectAttributes, "报名失败，原因：" + e.getMessage());
				// 订单状态更新为失效
				order.setStatus(Constant.Order.EMS_ORDER_STATUS_INVALID);
				order.setIsNewRecord(false);
				orderService.save(order);
				// return "redirect:"+Global.getFrontPath()+"/ems/joinForm?sign="+join.getCourse().getSign();
				// return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinForm";
				// return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
				throw e;
			}
			
			req.getSession().removeAttribute("token");
			// return "redirect:"+Global.getAdminPath()+"/ems/join/?repage";
			
			// pc端支付是否开放
			String isPcPay = Global.getConfig("isPcPay");
			if("true".equals(isPcPay))
			{
				return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinPay";
			}
			return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinTip";
			
		}
    	return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
    }
    
    @RequestMapping(value = "toQRcodePay")
	public String toQRcodePay(Join join, Model model,HttpServletRequest req) throws Exception {
    	Site site = CmsUtils.getSite(Site.defaultSiteId());
    	// pc端支付是否开放
		String isPcPay = Global.getConfig("isPcPay");
		if(!"true".equals(isPcPay))
		{
			return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
		}
		if(null == join || null == join.getOrder())
		{
			return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
		}
		
		Order order = this.orderService.get(join.getOrder().getId());
		
		if(null == order)
		{
			return "modules/cms/front/themes/"+site.getTheme()+"/frontIndex";
		}
		else
		{
			join.setOrder(order);
			model.addAttribute("payQRCodeUrl", getVDir("payQRCodePath") + "/" + order.getOrderNo() + ".png");
		}
		
		return "modules/cms/front/themes/"+site.getTheme()+"/frontJoinPay";
		
    }
    
    /**
     * 查询订单状态
     */
    @RequestMapping(value="/qryOrderStatus")
    @ResponseBody
    public Map<String,String> qryOrderStatus(String orderId) throws Exception {
    	
    	Map<String,String> rs = new HashMap<String,String>();
    	rs.put("rs", "fail");
    	Order order = this.orderService.get(orderId);
    	if(null != order)
    	{
    		// 若支付成功，则删除二维码
    		if(Constant.Order.EMS_ORDER_STATUS_SUCCESS.equals(order.getStatus()))
    		{
    			String qrcodePath = Global.getConfig("payQRCodePath");
    			File file1 = new File(qrcodePath+"/"+order.getOrderNo()+".png");
    			if(file1.isFile() && file1.exists())
    			{
    				file1.delete();
    				System.out.println("订单已支付，二维码删除成功。");
    				logger.info("订单已支付，二维码删除成功。");
    			}
    		}
    		
    		rs.put("rs", "success");
    		rs.put("status", order.getStatus());
    	}
    	
        return rs;
    }
    
    // 获取二维码虚拟目录
    public String getVDir(String path)
    {
    	String configPath = Global.getConfig("payQRCodePath");
    	if(null == configPath || configPath.indexOf('/') < 0)
    	{
    		return null;
    	}
    	String [] pathArr = configPath.split("/");
    	if(!configPath.endsWith("/"))
    	{
    		return "/" + pathArr[pathArr.length - 1];
    	}
    	else
    	{
    		return "/" +pathArr[pathArr.length - 2];
    	}
    }
    
}
